package com.credithc.signature.facade.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.credithc.signature.common.constant.ManagerConstant;
import com.credithc.signature.common.po.Channel;
import com.credithc.signature.common.po.OfficialSealTemplate;
import com.credithc.signature.common.po.SealChannel;
import com.credithc.signature.common.po.Template;
import com.credithc.signature.common.service.ChannelService;
import com.credithc.signature.common.service.OfficialSealTemplateService;
import com.credithc.signature.common.service.SealInfoService;
import com.credithc.signature.common.service.TemplateService;
import com.credithc.signature.common.utils.HttpUploadUtil;
import com.credithc.signature.facade.ro.RestSignatureReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @desc: <br/>
 * @author: Jingbo Hu<br/>
 * @time：2021年06⽉22⽇<br/>
 * @version：v1.0.0<br>
 */
@Slf4j
@Service
public class ParamVerifyService {

    @Value("${imageSize:10}")
    private long imageSize;

    @Value("${imageWidth:250}")
    private long imageWidth;

    @Value("${imageHeight:60}")
    private long imageHeight;

    @Autowired
    ChannelService channelService;

    @Autowired
    TemplateService templateService;

    @Autowired
    OfficialSealTemplateService sealTemplateService;

    @Autowired
    SealInfoService sealInfoService;

    /**
     * 校验渠道--旧签章
     *
     * @param channelId
     * @return
     */
    public boolean existChannel(String channelId) {
        Channel channel = channelService.selectCacheByChannelNo(channelId);
        if (Objects.isNull(channel)) {
            return false;
        }
        return true;
    }

    /**
     * 校验渠道--新签章
     *
     * @param encryptKey
     * @param restSignatureReq
     * @return
     */
    public boolean existChannel(String encryptKey, RestSignatureReq restSignatureReq) {
        String channelNo = restSignatureReq.getChannelNo();
        Channel channel = channelService.selectCacheByChannelNo(channelNo);
        if (Objects.isNull(channel) || !encryptKey.equals(channel.getEncryptKey())) {
            return false;
        }
        return true;
    }

    /**
     * 检查模板--旧签章
     *
     * @param templateId
     * @param channelId
     * @return
     */
    public boolean existTemplate(String templateId, String channelId) {
        Channel channel = channelService.selectCacheByChannelNo(channelId);
        Template template = templateService.selectCacheByTemplateNo(templateId);
        if (Objects.isNull(template) || !template.getTemplateStatus().equals(ManagerConstant.Enable) || !template.getChannelId().equals(channel.getId())) {
            return false;
        }
        return true;
    }

    /**
     * 检查模板--新签章
     *
     * @param restSignatureReq
     * @return
     */
    public boolean existTemplate(RestSignatureReq restSignatureReq) {
        String channelNo = restSignatureReq.getChannelNo();
        String templateNo = restSignatureReq.getTemplateNo();
        Template template = templateService.selectCacheByTemplateNo(templateNo);
        Channel channel = channelService.selectCacheByChannelNo(channelNo);
        if (Objects.isNull(template) || !template.getTemplateStatus().equals(ManagerConstant.Enable) || !template.getChannelId().equals(channel.getId())) {
            return false;
        }
        return true;
    }

    /**
     * 检查公章--旧签章
     *
     * @param channelId
     * @param templateId
     * @param isSeal
     * @return
     */
    public boolean existSeal(List<String> sealsCodes, String channelId, String templateId, int isSeal) {
        // 1、如果是私章返回true、如果不需要签章返回true
        Template template = templateService.selectCacheByTemplateNo(templateId);
        if (template.getSealType().equals(Integer.valueOf(ManagerConstant.PERSONAL)) || isSeal != 1) {
            return true;
        }

        // 2、校验公章，自定义公章和模板配置公章
        // 自定义公章为空
        if (CollectionUtils.isEmpty(sealsCodes)) {
            List<OfficialSealTemplate> ofst = sealTemplateService.selectByTemplateNo(templateId);
            List<SealChannel> sealChannels = sealInfoService.selectByChannelNo(channelId);
            List<SealChannel> collect1 = sealChannels.stream().filter(i -> ofst.stream().allMatch(k -> i.getSealCode().equals(k.getOfficialSealCode()))).collect(Collectors.toList());
            SealChannel channel = collect1.stream().filter(j -> j.getStatus().equals(ManagerConstant.DISABLE)).findAny().orElse(null);
            if (Objects.isNull(channel)) {
                return true;
            }
        } else {
            // 自定义公章不为空
            List<SealChannel> sealChannels = sealInfoService.selectByChannelNo(channelId);
            List<SealChannel> collect2 = sealChannels.stream().filter(i -> sealsCodes.stream().allMatch(k -> i.getSealCode().equals(k))).collect(Collectors.toList());
            SealChannel channel = collect2.stream().filter(j -> j.getStatus().equals(ManagerConstant.DISABLE)).findAny().orElse(null);
            if (Objects.isNull(channel)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查公章--新签章
     *
     * @param restSignatureReq
     * @return
     */
    public boolean existSeal(RestSignatureReq restSignatureReq) {
        // 1、如果是私章返回true、如果不需要签章返回true
        String templateNo = restSignatureReq.getTemplateNo();
        Boolean needSign = restSignatureReq.getNeedSign();
        Template template = templateService.selectCacheByTemplateNo(templateNo);
        if (template.getSealType().equals(Integer.valueOf(ManagerConstant.PERSONAL)) || !needSign) {
            return true;
        }

        // 2、校验公章，自定义公章和模板配置公章
        List<String> sealsCodes = restSignatureReq.getRequestData().getOfficialSealsCodes();
        String channelNo = restSignatureReq.getChannelNo();
        // 自定义公章为空
        if (CollectionUtils.isEmpty(sealsCodes)) {
            List<OfficialSealTemplate> ofst = sealTemplateService.selectByTemplateNo(templateNo);
            List<SealChannel> sealChannels = sealInfoService.selectByChannelNo(channelNo);
            List<SealChannel> collect1 = sealChannels.stream().filter(i -> ofst.stream().allMatch(k -> i.getSealCode().equals(k.getOfficialSealCode()))).collect(Collectors.toList());
            SealChannel channel = collect1.stream().filter(j -> j.getStatus().equals(ManagerConstant.DISABLE)).findAny().orElse(null);
            if (Objects.isNull(channel)) {
                return true;
            }
        } else {
            // 自定义公章不为空
            List<SealChannel> sealChannels = sealInfoService.selectByChannelNo(channelNo);
            List<SealChannel> collect2 = sealChannels.stream().filter(i -> sealsCodes.stream().allMatch(k -> i.getSealCode().equals(k))).collect(Collectors.toList());
            SealChannel channel = collect2.stream().filter(j -> j.getStatus().equals(ManagerConstant.DISABLE)).findAny().orElse(null);
            if (Objects.isNull(channel)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 校验手写签章图片
     *
     * @param restSignatureReq
     * @return
     */
    public boolean checkHandwritingImage(RestSignatureReq restSignatureReq) {
        if (!restSignatureReq.getNeedSign()) {
            return true;
        }
        List certInfos = restSignatureReq.getRequestData().getCertInfos();
        if (CollectionUtils.isNotEmpty(certInfos)) {
            List<byte[]> imageBytes = new ArrayList<>();
            List<String> imageUrls = new ArrayList<>();
            certInfos.stream().forEach(p -> {
                JSONObject object = JSONObject.parseObject(JSON.toJSONString(p));
                if (object.containsKey("sealImageBytes")) {
                    String strBytes = object.get("sealImageBytes").toString();
                    byte[] decodeBase64 = Base64.decodeBase64(strBytes);
                    imageBytes.add(decodeBase64);
                }
                if (object.containsKey("sealImageUrl")) {
                    String sealImageUrl = object.get("sealImageUrl").toString();
                    imageUrls.add(sealImageUrl);
                }
            });
            // 如果imageBytes不为空
            if (CollectionUtils.isNotEmpty(imageBytes)) {
                for (byte[] imageByte : imageBytes) {
                    return verifyImageLimit(imageByte, restSignatureReq);
                }
            }
            // 如果imageUrl不为空
            if (CollectionUtils.isNotEmpty(imageUrls)) {
                for (String url : imageUrls) {
                    byte[] imageByte = HttpUploadUtil.download(url);
                    return verifyImageLimit(imageByte, restSignatureReq);
                }
            }
        }
        return true;
    }

    /**
     * 校验图片参数
     *
     * @param imageByte
     * @param restSignatureReq
     * @return
     */
    private boolean verifyImageLimit(byte[] imageByte, RestSignatureReq restSignatureReq) {
        ByteArrayInputStream bais = new ByteArrayInputStream(imageByte);
        BufferedImage image = null;
        try {
            long size = imageByte.length / 1024L;
            image = ImageIO.read(bais);
            int width = image.getWidth();
            int height = image.getHeight();
            if (size > imageSize) {
                restSignatureReq.getRequestData().setHandWritingErrorMsg("手写图片大小超过限制,limit Value:" + imageSize + "KB");
                return false;
            }
            if (width > imageWidth) {
                restSignatureReq.getRequestData().setHandWritingErrorMsg("手写图片宽度超过限制,limit Value:" + imageWidth + "px");
                return false;
            }
            if (height > imageHeight) {
                restSignatureReq.getRequestData().setHandWritingErrorMsg("手写图片高度超过限制,limit Value:" + imageHeight + "px");
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
}
